#include "httpserver.h"

HttpServer::HttpServer(QWidget *parent)
    : QTcpServer(parent)
{
    //ui->setupUi(this);
    // 当有新的连接时，调用handleNewConnection槽
    connect(this, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection);
}

HttpServer::~HttpServer()
{
    //delete ui;
    close();  // 关闭服务器
}

void HttpServer::startServer(int port)
{
    if (!listen(QHostAddress::Any, port))  // 监听所有网络接口的指定端口
    {
        qDebug() << "服务器启动失败！";
    }
    else
    {
        qDebug() << "服务器已启动，监听端口：" << port;
    }
}

void HttpServer::handleNewConnection()
{
    while (hasPendingConnections())  // 检查是否有待处理的连接
    {
        QTcpSocket *clientSocket = nextPendingConnection();  // 获取新的客户端连接
        connect(clientSocket, &QTcpSocket::readyRead, this, [this, clientSocket]() {
            handleClientRequest(clientSocket);  // 处理客户端请求
        });
    }
}

void HttpServer::handleClientRequest(QTcpSocket *clientSocket)
{
    QTextStream in(clientSocket);  // 从客户端读取数据
    QString request = in.readAll();  // 读取完整的请求内容

    qDebug() << "客户端请求：" << request;

    // 解析请求行（第一行）
    QStringList requestLines = request.split("\r\n");
    QStringList requestLine = requestLines.first().split(" ");
    QString method = requestLine[0];  // 请求方法（如GET）
    QString path = requestLine[1];    // 请求路径（如/）

    qDebug() << "请求方法" << method << "请求路径" << path;

    // 根据请求路径构造响应
    QString response;

    /*if (method == "GET")
    {
        if (path == "/")  // 请求根路径，返回默认页面
        {
            response = "HTTP/1.1 200 OK\r\n"
                       "Content-Type: text/html; charset=UTF-8\r\n"
                       "Connection: close\r\n"
                       "\r\n"
                       "<html><body><h1>你好，世界！</h1></body></html>";
        }
        else if (path == "/file")  // 请求/file路径，返回文件内容
        {
            QString filePath = "D:/11.txt";  // 指定文件路径
            QString fileContent = readFile(filePath);  // 读取文件内容

            if (!fileContent.isEmpty())  // 如果文件内容不为空
            {
                response = "HTTP/1.1 200 OK\r\n"
                           "Content-Type: text/plain; charset=UTF-8\r\n"
                           "Connection: close\r\n"
                           "\r\n"
                           + fileContent;  // 返回文件内容
            }
            else
            {
                // response = "HTTP/1.1 404 Not Found\r\n"
                //            "Content-Type: text/plain; charset=UTF-8\r\n"
                //            "Connection: close\r\n"
                //            "\r\n"
                //            "文件未找到";  // 文件未找到时返回404
            }
        }
        else  // 其他路径返回404
        {
            response = "HTTP/1.1 404 Not Found\r\n"
                       "Content-Type: text/plain; charset=UTF-8\r\n"
                       "Connection: close\r\n"
                       "\r\n"
                       "404 Not Found";
        }
    }
    else  // 不支持其他HTTP方法
    {
        response = "HTTP/1.1 405 Method Not Allowed\r\n"
                   "Content-Type: text/plain; charset=UTF-8\r\n"
                   "Connection: close\r\n"
                   "\r\n"
                   "不支持的请求方法";
    }*/
    /*----------------------------------------------------------*/

    //能将数据正常的发送出去，通过HTTP的发送，上传文件
    if (method == "GET")
    {
        if (path == "/")  // 请求根路径，返回默认页面
        {
            response = "HTTP/1.1 200 OK\r\n"
                       "Content-Type: text/html; charset=UTF-8\r\n"
                       "Connection: close\r\n"
                       "\r\n"
                       "<html><body><h1>你好，世界！</h1></body></html>";
        }
        else if (path == "/file")  // 请求/file路径，返回文件内容
        {
            QString filePath = "D:/test/seat/seatface0.bmp";  // 指定文件路径
            QByteArray fileContent = readBMPFile(filePath);  // 读取文件内容

            if (!fileContent.isEmpty())  // 如果文件内容不为空
            {
                response = "HTTP/1.1 200 OK\r\n"
                           "Content-Type: image/bmp\r\n"
                           "Content-Disposition: attachment; filename=\"11.bmp\"\r\n"
                           "Content-Length: 60543990\r\n"
                           "Connection: close\r\n"
                           "\r\n";
                response += fileContent;  // 返回文件内容;
            }
            else
            {
                // response = "HTTP/1.1 404 Not Found\r\n"
                //            "Content-Type: text/plain; charset=UTF-8\r\n"
                //            "Connection: close\r\n"
                //            "\r\n"
                //            "文件未找到";  // 文件未找到时返回404
            }
        }
        else  // 其他路径返回404
        {
            response = "HTTP/1.1 404 Not Found\r\n"
                       "Content-Type: text/plain; charset=UTF-8\r\n"
                       "Connection: close\r\n"
                       "\r\n"
                       "404 Not Found";
        }
    }
    else  // 不支持其他HTTP方法
    {
        response = "HTTP/1.1 405 Method Not Allowed\r\n"
                   "Content-Type: text/plain; charset=UTF-8\r\n"
                   "Connection: close\r\n"
                   "\r\n"
                   "不支持的请求方法";
    }

    sendResponse(clientSocket, response);  // 发送响应给客户端
}

void HttpServer::sendResponse(QTcpSocket *clientSocket, const QString &response)
{
    QTextStream out(clientSocket);  // 创建文本流，用于向客户端发送数据
    //out.setCodec("UTF-8");  // 设置编码为UTF-8，确保中文显示正常
    out << response;  // 写入响应内容
    out.flush();  // 确保数据被发送

    clientSocket->disconnectFromHost();  // 主动断开与客户端的连接

    // 检查套接字是否已经处于未连接状态
    if (clientSocket->state() != QAbstractSocket::UnconnectedState)
    {
        clientSocket->waitForDisconnected();  // 等待连接断开
    }

    clientSocket->deleteLater();  // 释放客户端套接字资源
}

QString HttpServer::readTxtFile(const QString &filePath)
{
    QFile file(filePath);  // 创建文件对象
    if (!file.exists())  // 如果文件不存在
    {
        qDebug() << "文件不存在：" << filePath;
        return QString();  // 返回空字符串
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))  // 打开文件
    {
        qDebug() << "无法打开文件" << filePath;
        return QString();  // 返回空字符串
    }

    QString content = file.readAll();  // 读取文件内容
    file.close();  // 关闭文件
    return content;  // 返回文件内容
}

QByteArray HttpServer::readBMPFile(const QString &filePath){
    QFile file(filePath);  // 创建文件对象
    if (!file.exists())  // 如果文件不存在
    {
        qDebug() << "文件不存在：" << filePath;
        return QByteArray();  // 返回空字符串
    }

    if (!file.open(QIODevice::ReadOnly))  // 打开文件
    {
        qDebug() << "无法打开文件" << filePath;
        return QByteArray();  // 返回空字符串
    }

    QByteArray content = file.readAll();  // 读取文件内容
    file.close();  // 关闭文件
    return content;  // 返回文件内容
}
